package com.zpl.common.support.hook;

import com.github.houbb.heaven.util.util.DateUtil;
import com.zpl.common.api.Destroyable;
import com.zpl.common.support.invoke.IInvokeService;
import com.zpl.common.support.status.IStatusManger;
import lombok.extern.slf4j.Slf4j;

/**
 * @author zhupanlin
 * @version 1.0
 * @description: TODO
 * @date 2024/9/8 12:09
 */
@Slf4j
public class DefaultShutdownHook extends AbstractShutdownHook{


    /**
     * 调用管理类
     */
    private IInvokeService invokeService;

    /**
     * 销毁管理类
     */
    private Destroyable destroyable;

    /**
     * 状态管理类
     */
    private IStatusManger statusManger;
    
    private long waitMillsForRemainRequest = 60 * 1000;

    public IInvokeService getInvokeService() {
        return invokeService;
    }

    public void setInvokeService(IInvokeService invokeService) {
        this.invokeService = invokeService;
    }

    public Destroyable getDestroyable() {
        return destroyable;
    }

    public void setDestroyable(Destroyable destroyable) {
        this.destroyable = destroyable;
    }

    public IStatusManger getStatusManger() {
        return statusManger;
    }

    public void setStatusManger(IStatusManger statusManger) {
        this.statusManger = statusManger;
    }

    public long getWaitMillsForRemainRequest() {
        return waitMillsForRemainRequest;
    }

    public void setWaitMillsForRemainRequest(long waitMillsForRemainRequest) {
        this.waitMillsForRemainRequest = waitMillsForRemainRequest;
    }

    @Override
    protected void doHook() {
        statusManger.status(false);    
        // 设置状态为等待关闭
        log.info("[Shutdown] set status to wait for shutdown.");

        // 循环等待当前执行的请求执行完成
        long startMills = System.currentTimeMillis();
        while (invokeService.remainsRequest()) {
            long currentMills = System.currentTimeMillis();
            long costMills = currentMills - startMills;
            if (costMills >= waitMillsForRemainRequest) {
                log.warn("[Shutdown] still remains request, but timeout, break.");
                break;
            }

            log.debug("[Shutdown] still remains request, wait for a while.");
            DateUtil.sleep(100);
        }
        
        // 销毁
        destroyable.destroyAll();
        
        // 设置状态为关闭成功
        statusManger.status(false);
        log.info("[Shutdown] set status to shutdown success.");
    }
}
